﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using TileEngine.tiles;
using TileEngine.tiles.placable;

namespace TileEngine
{
    class LightEngine
    {
        public static int margin=10;
        public static int threshouldValue = 7;

        public static byte[,] lightr;
        public static byte[,] lightg;
        public static byte[,] lightb;
        static Point startTile;
        public static void startLighting()
        {
            lightr = new byte[(int)Camera.tilesOnScreen.X + 2 * margin+1, (int)Camera.tilesOnScreen.Y + 2 * margin+1];
            lightg = new byte[(int)Camera.tilesOnScreen.X + 2 * margin+1, (int)Camera.tilesOnScreen.Y + 2 * margin+1];
            lightb = new byte[(int)Camera.tilesOnScreen.X + 2 * margin+1, (int)Camera.tilesOnScreen.Y + 2 * margin+1];
        }
        public static Color getColor(int i, int j)
        {
            return new Color(lightr[i + margin, j + margin],
                             lightg[i + margin, j + margin],
                             lightb[i + margin, j + margin], 255);
        }
        static void spreadColor(byte[,] light, int i, int j, byte value)
        {
            if (i < 0 || j < 0 || i > Camera.tilesOnScreen.X+margin || j > Camera.tilesOnScreen.Y+margin)
                return;
            if (value < threshouldValue)
                return;
            if (light[i, j] >= value)
                return;
            light[i, j] = value;
            double absorption = 1;
            if (Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].wall != null)
                absorption *= Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].wall.getLightAbsorption();
            if (Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].liquid != null)
                absorption *= Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].liquid.getLightAbsorption();
            if (Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].tile.GetType() != typeof(Empty))
                absorption *= Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].tile.getLightAbsorption();

            byte newValue = Convert.ToByte(((double)value * absorption));
;
            //if(Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].liquid==null)
            //newValue = Convert.ToByte(((double)value * Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].tile.getLightAbsorption()));
            //else
            //newValue = Convert.ToByte(((double)value * Global.currentWorld.tiles[i + startTile.X, j + startTile.Y].liquid.getLightAbsorption()));
            spreadColor(light, i + 1, j, newValue);
            spreadColor(light, i - 1, j, newValue);
            spreadColor(light, i, j + 1, newValue);
            spreadColor(light, i, j - 1, newValue);

            //spreadColor(light, i + 1, j + 1, newValue);
            //spreadColor(light, i + 1, j - 1, newValue);
            //spreadColor(light, i - 1, j + 1, newValue);
            //spreadColor(light, i - 1, j - 1, newValue);
        }
        public static void calculateLights(Point startTile, Point endTile)//
        {
            LightEngine.startTile = startTile;
            startLighting();
            for (int x = startTile.X; x <= endTile.X; x++)
            {
                for (int y = startTile.Y; y <= endTile.Y; y++)
                {
                    if(Global.currentWorld.tiles[x,y].tile.GetType()==typeof(Torch))
                        {
                            spreadColor(lightr, x - startTile.X, y - startTile.Y, Global.currentWorld.tiles[x, y].tile.getLight().R);
                            spreadColor(lightg, x - startTile.X, y - startTile.Y, Global.currentWorld.tiles[x, y].tile.getLight().G);
                            spreadColor(lightb, x - startTile.X, y - startTile.Y, Global.currentWorld.tiles[x, y].tile.getLight().B);
                        }
                    if (Global.currentWorld.tiles[x, y].liquid == null && Global.currentWorld.tiles[x, y].wall == null)
                    {   
                        lightr[ x - startTile.X, y - startTile.Y]=200;
                        lightg[ x - startTile.X, y - startTile.Y]=200;
                        lightb[ x - startTile.X, y - startTile.Y]=200;
                        if (Global.currentWorld.tiles[x, y + 1].wall != null || Global.currentWorld.tiles[x, y - 1].wall != null
                            || Global.currentWorld.tiles[x, y - 1].tile.GetType() != typeof(Empty)
                            || Global.currentWorld.tiles[x - 1, y].tile.GetType() != typeof(Empty)
                            || Global.currentWorld.tiles[x + 1, y].tile.GetType() != typeof(Empty)
                            || Global.currentWorld.tiles[x, y + 1].tile.GetType() != typeof(Empty))
                        {
                            spreadColor(lightr, x - startTile.X, y - startTile.Y, Global.currentWorld.tiles[x, y].tile.getLight().R);
                            spreadColor(lightg, x - startTile.X, y - startTile.Y, Global.currentWorld.tiles[x, y].tile.getLight().G);
                            spreadColor(lightb, x - startTile.X, y - startTile.Y, Global.currentWorld.tiles[x, y].tile.getLight().B);
                        }
                    }
                }
            }
            //if (Global.currentWorld.player.inventory.holders[Global.currentWorld.player.inventory.selected].items.Count != 0){
            //    Color get = Global.currentWorld.player.inventory.holders[Global.currentWorld.player.inventory.selected].items[0].getLight();
            //    spreadColor(lightr, (int)Camera.tilesOnScreen.X / 2 + margin, (int)Camera.tilesOnScreen.Y / 2+margin, get.R);
            //    spreadColor(lightg, (int)Camera.tilesOnScreen.X / 2 + margin, (int)Camera.tilesOnScreen.Y / 2+margin, get.G);
            //    spreadColor(lightb, (int)Camera.tilesOnScreen.X / 2 + margin, (int)Camera.tilesOnScreen.Y / 2+margin, get.B);
            //}
        }
    }
}
